
#pragma once

#include "Common/Math.h"

#include "Pipeline.h"

namespace ttg_internal
{
	namespace utils
	{
		///<summary>
		/// Manages all pipelines.
		///</summary>
		private ref class PipelineManager sealed
		{
			private:
				static PipelineManager ^ref = nullptr;
			internal:
				///<summary>
				/// Inits manager. Should be called before using of "getRef()".
				///</summary>
				static void init()
				{ ref = gcnew PipelineManager(); }
				///<summary>
				/// Closes manager. Should be called after last using of "getRef()".
				///</summary>
				static void close()
				{
					delete ref;
					ref = nullptr;
				}
				///<summary>
				/// Returns reference to instance of ParameterManager.
				///</summary>
				static PipelineManager ^getRef()
				{ return ref; }
			private:
				ttg::math::uint64 curID;
				System::Collections::ObjectModel::ObservableCollection<Pipeline ^> ^_pipelines;
				System::Collections::Generic::Dictionary<ttg::math::uint64, Pipeline ^> ^_pipelineIDs;
			internal:
				///<summary>
				/// Creates empty manager.
				///<summary>
				PipelineManager()
				{
					curID = 0;
					_pipelines = gcnew System::Collections::ObjectModel::ObservableCollection<Pipeline ^>();
					_pipelineIDs = gcnew System::Collections::Generic::Dictionary<ttg::math::uint64, Pipeline ^>();
				}
				///<summary>
				/// Locks pipelines to avoid its modification.
				///</summary>
				void Lock()
				{ System::Threading::Monitor::Enter(this); }
				///<summary>
				/// UnLocks pipelines.
				///</summary>
				void UnLock()
				{ System::Threading::Monitor::Exit(this); }
				///<summary>
				/// Returns all registered pipelines.
				///</summary>
				property System::Collections::ObjectModel::ObservableCollection<Pipeline ^> ^Pipelines
				{
					System::Collections::ObjectModel::ObservableCollection<Pipeline ^> ^get()
					{ return _pipelines; }
				}
				///<summary>
				/// Creates wrapper for serialized pipeline and adds it to collection of registered pipelines.
				/// Returns ID of created wrapper.
				///</summary>
				ttg::math::uint64 createPipeline(ttg_internal::pipeline::LitePipelineInfo &pipeline);
				///<summary>
				/// Finds pipeline with required ID.
				/// In case of unexsistance returns nullptr.
				///</summary>
				Pipeline ^findPipeline(ttg::math::uint64 ID);
				///<summary>
				/// Releases pipeline with required ID.
				///</summary>
				void releasePipeline(ttg::math::uint64 ID);
		};
	}
}